/**
 * Candidate number: 35834
 */
package tv.starfu.animae;

import com.artemis.Entity;
import com.artemis.World;
import com.jme3.app.SimpleApplication;
import com.jme3.bullet.BulletAppState;
import com.jme3.bullet.collision.shapes.CapsuleCollisionShape;
import com.jme3.bullet.control.CharacterControl;
import com.jme3.input.ChaseCamera;
import com.jme3.input.InputManager;
import com.jme3.input.KeyInput;
import com.jme3.input.MouseInput;
import com.jme3.input.controls.ActionListener;
import com.jme3.input.controls.KeyTrigger;
import com.jme3.input.controls.MouseButtonTrigger;
import com.jme3.math.FastMath;
import com.jme3.math.Vector3f;
import com.jme3.renderer.Camera;
import com.jme3.scene.Geometry;
import com.jme3.scene.Node;

public class StarRacer extends Anima implements ActionListener {

    private BulletAppState bullet;
    private Node starRacer = new Node("starRacerNode");
    private Node level;

    public Node getStarRacer() {
        return starRacer;
    }

    public void setStarRacer(Node starRacer) {
        this.starRacer = starRacer;
    }
    private Camera cam;
    private ChaseCamera chaseCam;

    private CharacterControl avatar;
    private Vector3f walkDirection = new Vector3f();
    private boolean left = false, right = false, up = false, down = false;
    
    private InputManager inputManager;

    public StarRacer(World world, Entity owner, SimpleApplication app, Node root) {
        super(world, owner, app);
        this.cam = app.getCamera();
        this.level = root;
        this.bullet = app.getStateManager().getState(BulletAppState.class);
        this.inputManager = app.getInputManager();
    }

    @Override
    public void initalize() {        
        setUpKeys();
        buildStarRacer();
    }

    @Override
    public void render() {

        Vector3f camDir = cam.getDirection().clone().multLocal(0.9f);
        Vector3f camLeft = cam.getLeft().clone().multLocal(0.4f);
        walkDirection.set(0, 0, 0);
        if (left) {
            walkDirection.addLocal(camLeft);
        }
        if (right) {
            walkDirection.addLocal(camLeft.negate());
        }
        if (up) {
            walkDirection.addLocal(camDir);
        }
        if (down) {
            walkDirection.addLocal(camDir.negate());
        }
        walkDirection.addLocal(cam.getDirection().clone().multLocal(0.2f));
        avatar.setWalkDirection(walkDirection);
        cam.setLocation(avatar.getPhysicsLocation().clone().subtractLocal(new Vector3f(4, 2, 0)));

    }

    private void buildStarRacer() {
        CapsuleCollisionShape capsuleShape = new CapsuleCollisionShape(1.5f, 12f, 1);

        avatar = new CharacterControl(capsuleShape, 0.05f);

        avatar.setJumpSpeed(50);
        avatar.setFallSpeed(30);
        avatar.setGravity(30);
        
        starRacer.addControl(avatar);
        avatar.setPhysicsLocation(new Vector3f(0, 30, 0));

        //app.getRootNode().attachChild(starRacer);
        level.attachChild(starRacer);
        bullet.getPhysicsSpace().add(avatar);


    }

    private void setUpKeys() {
        inputManager.addMapping("Up", new KeyTrigger(KeyInput.KEY_W));
        inputManager.addMapping("Down", new KeyTrigger(KeyInput.KEY_S));
        inputManager.addMapping("Left", new KeyTrigger(KeyInput.KEY_A));
        inputManager.addMapping("Right", new KeyTrigger(KeyInput.KEY_D));

        inputManager.addMapping("Jump", new KeyTrigger(KeyInput.KEY_SPACE), new MouseButtonTrigger(MouseInput.BUTTON_LEFT));
        inputManager.addMapping("Shoot", new KeyTrigger(KeyInput.KEY_L));

        inputManager.addListener(this, new String[]{"Jump", "Shoot"});
        inputManager.addListener(this, new String[]{"Up", "Down", "Left", "Right"});
    }

    public void onAction(String binding, boolean value, float tpf) {
        if (binding.equals("Left")) {
            if (value) {
                left = true;
            } else {
                left = false;
            }
        } else if (binding.equals("Right")) {
            if (value) {
                right = true;
            } else {
                right = false;
            }
        } else if (binding.equals("Up")) {
            if (value) {
                up = true;
            } else {
                up = false;
            }
        } else if (binding.equals("Down")) {
            if (value) {
                down = true;
            } else {
                down = false;
            }
        } else if (binding.equals("Jump")) {
            avatar.jump();
        }

    }

    private void setupChaseCam() {
        app.getFlyByCamera().setEnabled(false);
        chaseCam = new ChaseCamera(cam, starRacer, app.getInputManager());
        chaseCam.setSmoothMotion(true);
        chaseCam.setDefaultDistance(40f);
        chaseCam.setDragToRotate(true);
        chaseCam.setMaxDistance(60f);
        chaseCam.setMinDistance(30f);
        chaseCam.setDefaultVerticalRotation(FastMath.QUARTER_PI*0.5f);
        chaseCam.setDefaultHorizontalRotation(-FastMath.HALF_PI);
        chaseCam.setTrailingEnabled(true);
        chaseCam.setTrailingRotationInertia(0.4f);  // not sure how much difference this makes...
        
    }
}
